package com.szx.kaihei.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.szx.kaihei.constants.JwtConstant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类 - 基于Hutool实现（静态方法版本）
 */
public class JwtUtil {

    // JWT签名算法
    private static final JWTSigner SIGNER = JWTSignerUtil.hs512(JwtConstant.JWT_SECRET.getBytes());

    /**
     * 生成JWT令牌
     * @param payload 载荷数据
     * @return JWT令牌
     */
    public static String generateToken(Map<String, Object> payload) {
        // 添加默认的签发时间和过期时间
        Map<String, Object> claims = new HashMap<>(payload);
        claims.put(JWT.ISSUED_AT, DateUtil.date());
        claims.put("exp", DateUtil.offsetMinute(DateUtil.date(), JwtConstant.JWT_EXPIRE));

        return JWTUtil.createToken(claims, SIGNER);
    }

    /**
     * 生成JWT令牌（简化版，仅包含用户ID）
     * @param userId 用户ID
     * @return JWT令牌
     */
    public static String generateToken(Long userId, String name) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("id", userId);
        payload.put("name", name);
        return generateToken(payload);
    }

    /**
     * 验证JWT令牌
     * @param token JWT令牌
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        if (StrUtil.isBlank(token)) {
            return false;
        }

        try {
            // 验证签名
            boolean verify = JWTUtil.verify(token, SIGNER);
            if (!verify) {
                return false;
            }

            // 验证过期时间
            JWTValidator.of(token).validateDate(new Date());

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从JWT令牌中获取载荷
     * @param token JWT令牌
     * @return 载荷Map
     */
    public static Map<String, Object> getPayload(String token) {
        if (StrUtil.isBlank(token)) {
            return new HashMap<>();
        }

        try {
            JWT jwt = JWTUtil.parseToken(token);
            return jwt.getPayload().getClaimsJson().toBean(Map.class);
        } catch (Exception e) {
            return new HashMap<>();
        }
    }

    /**
     * 从JWT令牌中获取指定字段
     * @param token JWT令牌
     * @param key 字段名
     * @return 字段值
     */
    public static Object getClaim(String token, String key) {
        Map<String, Object> payload = getPayload(token);
        return payload.get(key);
    }

    /**
     * 从JWT令牌中获取用户ID
     * @param token JWT令牌
     * @return 用户ID
     */
    public static String getUserId(String token) {
        Object userId = getClaim(token, "userId");
        return userId != null ? userId.toString() : null;
    }

    /**
     * 获取JWT令牌的过期时间
     * @param token JWT令牌
     * @return 过期时间
     */
    public static Date getExpirationDate(String token) {
        Object exp = getClaim(token, "exp");
        if (exp instanceof Date) {
            return (Date) exp;
        } else if (exp instanceof Long) {
            return new Date((Long) exp);
        }
        return null;
    }

    /**
     * 检查JWT令牌是否已过期
     * @param token JWT令牌
     * @return 是否已过期
     */
    public static boolean isExpired(String token) {
        Date expirationDate = getExpirationDate(token);
        return expirationDate != null && expirationDate.before(new Date());
    }

    /**
     * 刷新JWT令牌（延长过期时间）
     * @param token JWT令牌
     * @return 新的JWT令牌
     */
    public static String refreshToken(String token) {
        if (StrUtil.isBlank(token) || !validateToken(token)) {
            return null;
        }

        Map<String, Object> payload = getPayload(token);
        // 移除原有的过期时间，重新生成
        payload.remove("exp");

        return generateToken(payload);
    }
}
